package com.study.designpattern.Prototype;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class PrototypeTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        BaseInfo baseInfo = new BaseInfo("LWP");
        List<Integer> list=new ArrayList<>();
        list.add(5);
        Product product=new Product("1","2",3,4,list,baseInfo);
        Product clone=product.clone();
        System.out.println(product.toString());
        System.out.println(clone.toString());
        product.getBaseInfo().setCompanyName("ZL");
        product.getList().add(6);
        product.setPart3(33);
        System.out.println(product.toString());
        System.out.println(clone.toString());

    }
}

@AllArgsConstructor
@Data
@NoArgsConstructor
class Product implements Cloneable,Serializable {
    private static final long serialVersionUID = 42L;
    private String part1;
    private String part2;
    private int part3;
    private Integer part4;
    private List<Integer> list;
    private BaseInfo baseInfo;

    @Override
    public String toString() {
        return super.hashCode() + ":" + "Product{" +
                "part1='" + part1 + '\'' +
                ", part2='" + part2 + '\'' +
                ", part3=" + part3 +
                ", part4=" + part4 +
                ", list=" + list +
                ", baseInfo=" + baseInfo +
                '}';
    }

//    @Override
//    protected Product clone() throws CloneNotSupportedException {
//        Product clone= ((Product) super.clone());
//        //对BaseInfo的深拷贝
//        BaseInfo clone1=this.baseInfo.clone();
//        clone.setBaseInfo(clone1);
//        return clone;
//    }

    protected Product clone() {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try (ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream);) {
            oos.writeObject(this);
        } catch (IOException e) {
            e.printStackTrace();
        }
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        try (ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream)) {
            Product object = ((Product) ois.readObject());
            return object;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }
}
@NoArgsConstructor
@AllArgsConstructor
@Data
class BaseInfo implements Cloneable, Serializable {
        private static final long serialVersionUID = 42L;
        private String companyName;
        @Override
        public String toString() {
            return super.hashCode() + ":" + "BaseInfo{" +
                    "companyName='" + companyName + '\'' +
                    '}';
        }

        @Override
        protected BaseInfo clone() throws CloneNotSupportedException {
            return ((BaseInfo) super.clone());
        }
    }